package com.example.day41_opengl_camera1;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

/**
 * Description:绘制三角形
 * Created by Gdu on 2021/4/24 19:30.
 */

public class TriangleRender implements GLSurfaceView.Renderer {

    //openGL 运行有2个程序 一个是顶点程序 可以直接运行
    private final String vertexShaderCode =
            "attribute vec4 vPosition; " +
                    "void main() {" +
                    "gl_Position = vPosition;" +
                    "}";
    //一个是片元程序  目的是为了上色
    private final String fragmentShaderCode =
            "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main() {" +
                    "  gl_FragColor = vColor;" +
                    "}";

    private FloatBuffer vertexBuffer;
    //顶点形状
    static float triangleColors[] = {
            0.5f, 0.5f, 0.0f, //top
            -0.5f, -0.5f, 0.0f, //bottom left
            0.5f, -0.5f, 0.0f, //bottom right
    };
    private int program;
    //颜色
    float color[] = {1.0f,0f,0f,1.0f};

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //将背景重置为灰色
        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        //申请底层空间
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(triangleColors.length * 4);
        //让GPU重新整理下内存
        byteBuffer.order(ByteOrder.nativeOrder());
        //到GPU申请内存
        vertexBuffer = byteBuffer.asFloatBuffer();
        vertexBuffer.put(triangleColors);
        vertexBuffer.position(0);

        //创建一个顶点程序 类似句柄,指向GPU的位置
        int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        //将源码传给GPU
        GLES20.glShaderSource(vertexShader, vertexShaderCode);
        //编译顶点程序 然后就可以用了
        GLES20.glCompileShader(vertexShader);
        //创建片元程序
        int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        //将源码传给GPU
        GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
        //编译
        GLES20.glCompileShader(fragmentShader);

        //创建一个大的程序,添加顶点程序和片元程序
        program = GLES20.glCreateProgram();
        //添加程序
        GLES20.glAttachShader(program,vertexShader);
        GLES20.glAttachShader(program,fragmentShader);
        //在GPU中链接两个程序,并且生成一个可执行的程序
        GLES20.glLinkProgram(program);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //设置宽高
        GLES20.glViewport(0,0,width,height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        //开始使用
        GLES20.glUseProgram(program);
        //第一步进行赛程序
        //得到源码程序里的变量引用
        int mPositionHandle = GLES20.glGetAttribLocation(program, "vPosition");
        //让GPU允许CPU往变量里写数据
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        //往变量写数据
        //第一个值是地址,第二是顶点个数,第三个是类型,我是float类型,第四个是自己执行,一般传false,第五个是一行有多少字节,第六是我的数据
        GLES20.glVertexAttribPointer(mPositionHandle,3,GLES20.GL_FLOAT,false,3*4,vertexBuffer);
        //第二部进行通知渲染
        //得到片元程序的应用
        int mColorHandle = GLES20.glGetUniformLocation(program, "vColor");
        //设置颜色
        GLES20.glUniform4fv(mColorHandle,1,color,0);
        //绘制三角形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3);
        //禁止别人使用顶点数组的句柄
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}
